import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;

import weka.classifiers.Classifier;
import weka.classifiers.Evaluation;
import weka.core.Instances;
import br.uninove.ic.texture.IGrayScaleImage;
import br.uninove.ic.texture.utils.ImageBuilder;
import br.uninove.jimage.dao.JImageDao;
import br.uninove.jimage.datamining.ClassificadorDao;
import br.uninove.jimage.delegate.JImageDelegate;
import br.uninove.jimage.to.MetodosDeClassificacaoTO;

public class ClasseTreinamento {

	private static Map<String, Set<IGrayScaleImage>> dados;

	public static void main(String[] args) {

		JImageDao dao = new JImageDao();
		JImageDelegate delegate = new JImageDelegate();
		List<MetodosDeClassificacaoTO> metodos = dao
				.findAllMetodosDeClassificacao();
		String pastaTreinamento = "C:/treinamento";
		String testes = "C:/testes";

		Map<String, Set<IGrayScaleImage>> dados = getDados(delegate,
				pastaTreinamento);

		Classifier classifier = fazerTreinamento(dados, metodos,
				pastaTreinamento);

		fazerClassificacao(metodos, testes, dados, classifier);
	}

	private static void fazerClassificacao(
			List<MetodosDeClassificacaoTO> metodos, String testes,
			Map<String, Set<IGrayScaleImage>> dados, Classifier classifier) {
		File[] files = new File(testes).listFiles();
		for (int i = 0; i < files.length; i++) {
			File[] images = files[i].listFiles();
			int certo = 0;
			int errado = 0;
			for (int j = 0; j < images.length; j++) {
				try {
					File file = images[j];
					IGrayScaleImage img = ImageBuilder.loadImageGrayScale(file);
					Instances isnt = ClassificadorDao.montaInstace(img,
							new Object[] { metodos.get(0), metodos.get(1) },
							dados);
					String classe = ClassificadorDao.classeDaImagem(classifier,
							isnt);

					if (deuCerto(file.getAbsolutePath(), classe)) {
						certo++;
					} else {
						errado++;
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			System.out.println("Na Classe " + files[i].getName() + " tivemos "
					+ certo + " certas e " + errado + " erradas");
		}
	}

	private static boolean deuCerto(String oquedeu, String oquedeveriaser) {
		oquedeu = oquedeu.substring(0, oquedeu.lastIndexOf("\\"));
		oquedeu = oquedeu.substring(oquedeu.lastIndexOf("\\") + 1, oquedeu
				.length());

		oquedeveriaser = oquedeveriaser.substring(oquedeveriaser
				.lastIndexOf("\\") + 1, oquedeveriaser.length());
		if (oquedeu.equals(oquedeveriaser)) {
			return true;
		}
		return false;
	}

	private static Map<String, Set<IGrayScaleImage>> getDados(
			JImageDelegate delegate, String pastaTreinamento) {
		File[] files = new File(pastaTreinamento).listFiles();
		String[] pastas = new String[files.length];
		for (int i = 0; i < files.length; i++) {
			pastas[i] = files[i].getAbsolutePath();
		}
		dados = delegate.lerImagens(pastas);
		return dados;
	}

	private static Classifier fazerTreinamento(
			Map<String, Set<IGrayScaleImage>> dados,
			List<MetodosDeClassificacaoTO> metodos, String pastaTreinamento) {
		Classifier classifier;

		Instances inst = ClassificadorDao.criarArff(new Object[] {
				metodos.get(0), metodos.get(1) }, dados);
		classifier = ClassificadorDao.criarClassificarJ48(inst);
		try {
			Evaluation evaluation = new Evaluation(inst);
			evaluation.evaluateModel(classifier, inst);
			// Quantos instances foram corretos
			System.out.print(evaluation.correct() + "/");
			// Quantos instances no total
			System.out.println(inst.numInstances());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return classifier;
	}
}
